home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 July: Mac OS SDK / Dev.CD Jul 96 SDK / Dev.CD Jul 96 SDK2.toast / Development Kits (Disc 2) / QuickDraw GX / Programming Stuff / Sample Code / Printing Samples / Printer Drivers… / HPXL / ChooserSupport.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-10  |  10.3 KB  |  360 lines  |  [TEXT/MPS ]

  1. /*---------------------------------------------------------------------------
  2. FILENAME
  3.     ChooserSupport.c
  4.  
  5. DESCRIPTION
  6.     This file contains the C code for the PACK and LDEF routines used by the
  7.     Chooser when the HPXL driver is selected in the Chooser.
  8.         
  9. COPYRIGHT
  10.     Copyright Apple Computer, Inc. 1993-1994
  11.     All rights reserved. 
  12.     
  13. INTERFACE ROUTINES:
  14.     Device
  15.     LDEF
  16.  
  17.     12/20/93        dmh        Sync'd up for GX 1.0b3.
  18.      8/28/94        dmh        Sync'd up for GX 1.0.1.
  19.  
  20. -------------------------------------------------------------------------------- */
  21.  
  22. #include <Types.h>
  23. #include <QuickDraw.h>
  24. #include <Fonts.h>
  25. #include <Lists.h>
  26. #include <Devices.h>
  27. #include <Resources.h>
  28. #include <Script.h>
  29. #include <ToolUtils.h>
  30. #include <LowMem.h>
  31.  
  32. // Include the new QuickDraw GX graphics header files 
  33. #include <graphics routines.h>
  34.  
  35. // Include the required Printing Manager header files 
  36. #include <PrintingDrivers.h>
  37.  
  38. /*********************************************************************************
  39.  *                                         CONSTANTS                                                     *
  40.  *********************************************************************************/
  41.  
  42. // Chooser initialize message selector
  43. #define    initializeMsg            11
  44.  
  45. // Icon Suite support
  46.  
  47. #define    ttNone                    0x0000
  48. #define    ttDisabled                0x0001
  49. #define    ttOffline                0x0002
  50. #define    ttOpen                    0x0003
  51. #define    ttSelected                 0x4000
  52. #define    ttSelectedDisabled    (ttSelected + ttDisabled)
  53. #define    ttSelectedOffline        (ttSelected + ttOffline)
  54. #define    ttSelectedOpen            (ttSelected + ttOpen)
  55.  
  56. #define    ttLabel0                    0x0000
  57. #define    ttLabel1                    0x0100
  58. #define    ttLabel2                    0x0200
  59. #define    ttLabel3                    0x0300
  60. #define    ttLabel4                    0x0400
  61. #define    ttLabel5                    0x0500
  62. #define    ttLabel6                    0x0600
  63. #define    ttLabel7                    0x0700
  64.  
  65.  
  66. /*********************************************************************************
  67.  *                                    INLINE DECLARATIONS                                            *
  68. **********************************************************************************/
  69.  
  70. pascal OSErr PlotIconSuite(const Rect * theRect, short align, short iconTransform, Handle cIcon)
  71.     = {0x303C, 0x0603, 0xABC9};
  72.  
  73. pascal void OldDrawText(const void *textBuf,short firstByte,short byteCount)
  74.     = 0xA885; 
  75.  
  76.  
  77. /***************************************************************************************
  78. *                                         INTERFACE ROUTINES                                                     *
  79. ***************************************************************************************/                        
  80.  
  81.  
  82. /****************************************************************************************
  83.  
  84.                             Device
  85.                             
  86.     function:
  87.                 This routine is the interface routine for the Chooser PACK.  This is the
  88.                 routine the Chooser calls to perform the Chooser functions for the 
  89.                 LaserWriter IISC driver.
  90.                 
  91.     parameters:                
  92.                 message        specifies which Chooser function to perform    
  93.                 caller        equals 1; specifies the caller is the Chooser
  94.                 objName        name of the selected device
  95.                 zoneName        zone name for AppleTalk devices
  96.                 theList        the list of names
  97.                 p2                parameter used depending upon message value
  98.                 
  99.     returns:
  100.                 OSErr
  101.     
  102. ****************************************************************************************/
  103. pascal OSErr Device(short message, short caller, StringPtr objName, 
  104.                     StringPtr zoneName, ListHandle theList, long p2)
  105. {
  106.     
  107.     OSErr            anErr = noErr;
  108.     extern Str31     gDriverName;
  109.     StringPtr        pDriverName = &gDriverName;
  110.     extern gxJob    gJob;                        // Declared in our .a file.
  111.     gxJob            *pJob = &gJob;
  112.  
  113.     if (message == initializeMsg)    // InitializeMsg--start up GX
  114.     {
  115.         FCBPBRec    pb;
  116.  
  117.     /*
  118.         Get the name of our driver for GXHandleChooserMessage.
  119.         (The user may have renamed us.)
  120.     */
  121.         pb.ioCompletion     = nil;
  122.         pb.ioNamePtr         = pDriverName;
  123.         pb.ioVRefNum         = 0;
  124.         pb.ioRefNum         = CurResFile();
  125.         pb.ioFCBIndx         = 0;
  126.         anErr = PBGetFCBInfo(&pb, false);
  127.  
  128.     /*
  129.         Clear *pJob, because it hasn't been initialized yet.  That doesn't
  130.         happen until we pass GXHandleChooserMessage an initializeMsg.
  131.     */
  132.         *pJob = nil;
  133.  
  134.     /*
  135.         We need to initialize GX printing so that we can call
  136.         GXHandleChooserMessage.  Since printing requires a graphics
  137.         client, call GXEnterGraphics first.  If there are errors,
  138.         (for example, due to memory limitations), post an alert.
  139.     */
  140.         if (anErr == noErr)
  141.         {
  142.             GXEnterGraphics();
  143.             anErr = GXGetGraphicsError(nil);
  144.             if (anErr == noErr)
  145.             {
  146.                 anErr = GXInitPrinting();
  147.                 if (anErr != noErr)
  148.                     GXExitGraphics();
  149.             }
  150.                 
  151.             if (anErr != noErr)
  152.                 StopAlert(-4095, nil);
  153.         }
  154.     }
  155.  
  156. /*
  157.     If the Chooser hasn't created a job yet, do nothing unless we were
  158.     sent an initializeMsg.  In its default implementation of
  159.     GXHandleChooserMessage, QuickDraw GX will create the job for our
  160.     driver when it receives an initializeMsg.  It will store a reference
  161.     to it in our pJob pointer.
  162.     
  163.     For all other messages, if a job has been created, call
  164.     GXHandleChooserMessage to handle things.
  165. */
  166.     if (anErr == noErr)
  167.     {
  168.         if ((*pJob != nil) || (message == initializeMsg))
  169.         {
  170.             anErr = GXHandleChooserMessage(pJob, pDriverName, message, caller, objName, zoneName, theList, p2);
  171.     
  172.         /*
  173.             If we just got a terminateMsg, and p2 is also terminateMsg, the
  174.             Chooser is closing.  QuickDraw GX just disposed of the gxJob it
  175.             created earlier when GXHandleChooserMessage was passed
  176.             initializeMsg, so we just need to call GXExitPrinting and
  177.             GXExitGraphics to clean up.
  178.             
  179.             Note that we must test the p2 parameter, because the Chooser
  180.             can also send terminateMsg when it wants to empty the device
  181.             list, but not dispose of us.  For example, this will happen
  182.             when the user turns off AppleTalk in the Chooser.
  183.         */
  184.             if ((message == terminateMsg) && (p2 == terminateMsg))
  185.             {
  186.                 GXExitPrinting();
  187.                 GXExitGraphics();
  188.             }
  189.         }
  190.     }
  191.         
  192.     return(anErr);
  193.     
  194. } // Device
  195.  
  196.  
  197.  
  198. // ------------------------------------------------------------------------
  199. // ENTRY POINT FOR LDEF
  200. // ------------------------------------------------------------------------
  201.  
  202. pascal void LDEF(
  203.     short         message,        // What operation to perform on list
  204.     Boolean     select,            // Is this cell to be selected or not?
  205.     Rect        *theRect,        // Rectangle of this cell, clipped to window
  206.     Cell        theCell,        // Which cell this is
  207.     short        dataOffset,        // Offset into data for this cell
  208.     short        dataLen,        // Length of data for this cell
  209.     ListHandle    theList)        // The list to act upon
  210. /*
  211.     An LDEF that works in two modes:
  212.         - if the first two characters of the cell are valid AppleTalk NBP names (ie, not ≈ ≈)
  213.           then the LDEF is just a basic text LDEF
  214.         - otherwise, it assumes the data is part of a PortListRec, which is
  215.           a structure for icons with text underneath
  216. */
  217.  
  218. {
  219. #pragma unused (theCell, dataLen)
  220.  
  221.     gxPortListRec        theCellContents;
  222.     Rect                iconRect;
  223.     unsigned char        hiliteMode;
  224.     
  225.     switch (message)
  226.         {
  227.         case lDrawMsg:
  228.         case lHiliteMsg:
  229.         
  230.             // save the data to avoid locking things down
  231.             if (dataLen > sizeof(theCellContents) )
  232.                 dataLen = sizeof(theCellContents);
  233.             BlockMove(((*(**theList).cells) + dataOffset), &theCellContents, dataLen );
  234.             
  235.             // draw the cell as an icon, but only if we see our magic marker at the front
  236.             if ( (theCellContents.firstMarker == '≈') && (theCellContents.secondMarker == '≈') )
  237.                 {
  238.                 // center the icon rect on the list with a top margin of 10 pixels
  239.                 iconRect.top = theRect->top + 10;
  240.                 iconRect.left = theRect->left + ((theRect->right - theRect->left) >> 1) - 16;
  241.                 iconRect.bottom = iconRect.top + 32;
  242.                 iconRect.right = iconRect.left + 32;
  243.                 
  244.                 
  245.                 // draw the icon
  246.                 if (theCellContents.iconSuiteHandle != nil)
  247.                     PlotIconSuite(&iconRect,
  248.                             ttNone, (select) ? ttSelected: ttNone,
  249.                             theCellContents.iconSuiteHandle);
  250.                             
  251.                 // Get the general area under the icon in which to draw the label
  252.                 iconRect.left = theRect->left + 2;
  253.                 iconRect.right = iconRect.left + (**theList).cellSize.h - 2;
  254.                 iconRect.top = iconRect.bottom + 2;
  255.                 iconRect.bottom = theRect->bottom;
  256.     
  257.                 // use a nice small font for the label            
  258.                 TextFont(applFont);
  259.                 TextSize(9);
  260.                 
  261.                     {
  262.                     short        labelWidth;
  263.                     short        rectWidth;
  264.                     short        labelHeight;
  265.                     FontInfo    theInfo;
  266.                 
  267.                     // Get rid of any text that was there before
  268.                     EraseRect(&iconRect);
  269.                     iconRect.top += 2;
  270.                     
  271.                     // compute the height of the label                    
  272.                     GetFontInfo(&theInfo);
  273.                     labelHeight = theInfo.ascent + theInfo.leading;
  274.                     
  275.                     // compute where to draw the text
  276.                     iconRect.bottom = iconRect.top + labelHeight;
  277.                     rectWidth = iconRect.right-iconRect.left;
  278.                     
  279.                     // truncate the string to fit within the box
  280.                     TruncString(rectWidth, theCellContents.iconName, smTruncEnd);
  281.                     
  282.                     // compute the new width of the string
  283.                     labelWidth = StringWidth(theCellContents.iconName);
  284.                     
  285.                     // center the string, draw it
  286.                     iconRect.left += (rectWidth >> 1) - (labelWidth >> 1);
  287.                     MoveTo(iconRect.left, iconRect.bottom);
  288.                     DrawString(theCellContents.iconName);
  289.                     
  290.                     if (select)
  291.                         {
  292.                         // compute right and lower edge of box bounding the text we just drew
  293.                         iconRect.right = iconRect.left + labelWidth;
  294.                         iconRect.bottom += theInfo.descent;
  295.                         
  296.                         // outset it, and invert it to select it
  297.                         InsetRect(&iconRect, -1, -1);
  298.                         hiliteMode = LMGetHiliteMode();
  299.                         BitClr(&hiliteMode, pHiliteBit);
  300.                         LMSetHiliteMode(hiliteMode);
  301.                         InvertRect(&iconRect);
  302.                         }
  303.                     }
  304.                     
  305.                 TextFont(applFont);
  306.                 TextSize(0);
  307.                 }
  308.             else
  309.                 {
  310.                 // how boring!  It's only text
  311.                 FontInfo    theInfo;
  312.                 Rect        ourRect;
  313.                 short        cellWidth;
  314.                 
  315.                 // add a margin to the rectangle
  316.                 ourRect = *theRect;
  317.                 ourRect.left += 4;
  318.                 --ourRect.right;
  319.                 cellWidth = ourRect.right - ourRect.left;
  320.                 
  321.                 // erase the rectangle
  322.                 GetFontInfo(&theInfo);
  323.                 EraseRect(theRect);
  324.                 MoveTo(ourRect.left, ourRect.bottom - theInfo.descent);
  325.                 
  326.                 // hey, you can't park that string here -- it's too big!
  327.                 if (TextWidth((Ptr) &theCellContents, 0, dataLen) > cellWidth )
  328.                     {
  329.                     // condense the text first
  330.                     TextFace(condense);
  331.                     
  332.                     // then truncate afterwards
  333.                     TruncText(cellWidth, (Ptr) &theCellContents, &dataLen, smTruncEnd);
  334.                     }
  335.                     
  336.                 // those darn other languages!
  337.                 if (GetSysJust() == teJustRight)
  338.                     Move(cellWidth-TextWidth((Ptr) &theCellContents, 0, dataLen) , 0);
  339.                     
  340.                 OldDrawText((Ptr) &theCellContents, 0, dataLen);
  341.                 
  342.                 // if selected, invert it
  343.                 if (select)
  344.                     {
  345.                     hiliteMode = LMGetHiliteMode();
  346.                     BitClr(&hiliteMode, pHiliteBit);
  347.                     LMSetHiliteMode(hiliteMode);
  348.                     InvertRect(theRect);
  349.                     }
  350.                     
  351.                 // normal text again
  352.                 TextFace(normal);
  353.                 }
  354.                 
  355.             break;
  356.             
  357.         } // switch
  358.         
  359. } // LDEF
  360.